package com.test.util;

import com.alibaba.cloudapi.sdk.client.ApacheHttpClient;
import com.alibaba.cloudapi.sdk.constant.SdkConstant;
import com.alibaba.cloudapi.sdk.enums.HttpMethod;
import com.alibaba.cloudapi.sdk.enums.ParamPosition;
import com.alibaba.cloudapi.sdk.enums.Scheme;
import com.alibaba.cloudapi.sdk.model.ApiRequest;
import com.alibaba.cloudapi.sdk.model.ApiResponse;
import com.alibaba.cloudapi.sdk.model.HttpClientBuilderParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.Getter;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;


@Component
public class OcrUtil extends ApacheHttpClient {

    @Data
    public static class OcrResponse {
        private String status;
        private String apiInvokeId;
        private OcrData data;
        private String subErrCode;
        private String subErrMessage;
        private String errCode;
        private String errMessage;
        private String startTime;
        private String endTime;

        @Data
        public static class OcrData {
            @JsonProperty("OcrInfo")
            private List<OcrInfo> ocrInfo;

        }

        @Data
        public static class OcrInfo {
            @JsonProperty("Text")
            private String text;
            @JsonProperty("Detail")
            private List<Detail> detail;

        }

        @Data
        public static class Detail {
            @JsonProperty("Type")
            private String type;
            @JsonProperty("Value")
            private String value;
            @JsonProperty("Confidence")
            private Float confidence;
            @JsonProperty("InGraph")
            private Boolean inGraph;
            @JsonProperty("ColumnIndex")
            private Integer columnIndex;
            @JsonProperty("RowIndex")
            private Integer rowIndex;
            @JsonProperty("ColumnSpan")
            private Integer columnSpan;
            @JsonProperty("RowSpan")
            private Integer rowSpan;
        }
    }

    public final static String OCR_URL = "openai.edu-aliyun.com";
    public final static String KEY_ID = "PUi92QiC";
    public final static String KEY_SECRET = "PGXW7vBZ3TBhmED87ss";
    public final static String PATH = "/scc/sc-ocr-common";


    public ApiResponse invoke(String path, Object params) {
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] body = null;
        try {
            body = objectMapper.writeValueAsString(params).getBytes(SdkConstant.CLOUDAPI_ENCODING);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ApiRequest request = new ApiRequest(HttpMethod.POST_BODY, path, body);
        return sendSyncRequest(request);
    }

    public ApiResponse invoke(String path, Object params, Map<String, String> headers) {
        byte[] body = null;
        try {
            body = JSON.toJSONString(params).getBytes(SdkConstant.CLOUDAPI_ENCODING);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ApiRequest request = new ApiRequest(HttpMethod.POST_BODY, path, body);
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                request.addParam(entry.getKey(), entry.getValue(),
                        ParamPosition.HEAD, false);
            }
        }
        return sendSyncRequest(request);
    }

    public ApiResponse invoke(ApiRequest request) {
        return sendSyncRequest(request);
    }

    public OcrResponse invoke(String imageUrl) {
        init();
        Map<String, String> params = new HashMap<>();
        params.put("dataBase64", convertImageToBase64(imageUrl));
        Map<String, String> headers = new HashMap<>();
        headers.put("x-scc-version", "");
        ApiResponse apiResponse = invoke(PATH, params, headers);
        //错误处理
        String s = new String(apiResponse.getBody(), StandardCharsets.UTF_8);
        return JSONObject.parseObject(s, OcrResponse.class);
    }

    private void init() {
        HttpClientBuilderParams httpClientBuilderParams = new HttpClientBuilderParams();
        httpClientBuilderParams.setScheme(Scheme.HTTPS);
        httpClientBuilderParams.setHost(OCR_URL);
        httpClientBuilderParams.setAppKey(KEY_ID);
        httpClientBuilderParams.setAppSecret(KEY_SECRET);
        httpClientBuilderParams.setConnectionTimeout(5000L);
        super.init(httpClientBuilderParams);
    }

    public static String convertImageToBase64(String imageUrl) {
        try (InputStream inputStream = new URL(imageUrl).openStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            return "data:image/jpeg;base64," + Base64.getEncoder()
                    .encodeToString(outputStream.toByteArray())
                    .replaceAll("\\s", "");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

//    public static void main(String[] args) {
//        OcrUtil.getInstance().init();
//        String path = "/scc/sc-ocr-common";
//        String imageUrl = "https://filetest4.drstrong.cn/doctor/images/feedback/1003737/fac19931aacb419e8b73d7bb71a72c7d";
//        String imageToBase64 = convertImageToBase64(imageUrl);
//        Map<String, String> params = new HashMap<>();
//        params.put("dataBase64", imageToBase64);
//        Map<String, String> headers = new HashMap<>();
//        headers.put("x-scc-version", "");
//        ApiResponse apiResponse = OcrUtil.getInstance().invoke(path, params, headers);
//        byte[] body = apiResponse.getBody();
//        String rawJson = new String(body, StandardCharsets.UTF_8);
//        OcrResponse ocrResponse = JSONObject.parseObject(rawJson, OcrResponse.class);
//        System.out.println("=================" + JSONObject.toJSONString(ocrResponse));
//    }


}
